package club.jdiy.core.job.config;

import club.jdiy.core.convert.Converter;
import club.jdiy.core.job.entity.JDiyJob;
import club.jdiy.core.job.entity.JDiyJobLog;
import club.jdiy.core.job.service.JDiyJobLogService;
import club.jdiy.core.job.exec.HandlerException;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;

import static club.jdiy.core.job.exec.JobHandler.TASK_PROPERTIES;

/**
 * JDiy计划任务执行事件监听程序.
 *
 * @author ziquee(子秋) QQ号:39886616 主页: http://www.jdiy.club
 * @version 20210622
 */
@Slf4j
@Component
public class QrtzJobListener implements JobListener {

    @Override
    public String getName() {
        return getClass().getSimpleName();
    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext arg0) {
        //log.info("Scheduler在JobDetail即将被执行，但又被TriggerListerner否决");
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext context) {
        try {
            JDiyJob job = (JDiyJob) context.getMergedJobDataMap().get(TASK_PROPERTIES);
            if (job != null && Boolean.TRUE.equals(job.getJobLog())) {
                jDiyJobLogService.save(JDiyJobLog.jobStartLog(job, context.getScheduledFireTime()));
            } else {//当JDiyJob运行日志不写到数据库时，就将日志打印到控制台
                JobDetail jd = context.getJobDetail();
                String cl = "jobStart: " + jd.getKey().getName()
                        + "@" + jd.getKey().getGroup()
                        + " {class: " + jd.getJobClass().getName() + "" +
                        (
                                CronTrigger.class.isAssignableFrom(context.getTrigger().getClass())
                                        ? "  cron: " + ((CronTrigger) context.getTrigger()).getCronExpression()
                                        : ""
                        ) + "}";
                log.info(cl);
            }
        } catch (Exception ignore) {
        }
    }

    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException ex) {
        try {
            String errMsg;
            if (ex != null) {
                Throwable t = ex;
                int m = 10;
                while (!HandlerException.class.isAssignableFrom(t.getClass()) && m-- > 0)
                    t = t.getCause();
                errMsg = t.getCause().toString();
            } else {
                errMsg = null;
            }

            JDiyJob job = (JDiyJob) context.getMergedJobDataMap().get(TASK_PROPERTIES);
            if (job != null && Boolean.TRUE.equals(job.getJobLog())) {
                jDiyJobLogService.findById(JDiyJobLog.createLogId(Converter.of(context.getScheduledFireTime()).getLocalDateTime(), job.getId()))
                        .ifPresent(p -> {
                            if (errMsg != null) {
                                p.setErrMessage(errMsg);
                                p.setState(2);
                            } else {
                                p.setState(0);
                            }
                            p.setEndTime(LocalDateTime.now());
                            jDiyJobLogService.save(p);
                        });
            } else {//当JDiyJob运行日志不写到数据库时，就将日志打印到控制台
                JobDetail jd = context.getJobDetail();
                String cl = "jobEnd: " + jd.getKey().getName()
                        + "@" + jd.getKey().getGroup()
                        + " {" + (errMsg == null ? "SUCCESS" : "errorMsg: " + errMsg) + "}";
                log.info(cl);
            }
        } catch (Exception ignore) {
        }
    }

    @Resource
    private JDiyJobLogService jDiyJobLogService;
}